package com.tender.desensitization.factory.instance;

import com.tender.properties.AppConfigProperties;
import com.tender.utils.ApplicationContextUtil;
import com.tender.desensitization.FieldReflectUtils;
import com.tender.desensitization.filter.FieldDecryptionFilter;
import com.tender.desensitization.filter.FieldFilter;
import com.tender.utils.AESUtil;
import com.tender.utils.SecretContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.Base64;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
public class DecryptionUserWrapperProcessFactory extends AbstractUserWrapperProcessFactory {

    public DecryptionUserWrapperProcessFactory(TypeProcessFactoryFacade factoryFacade) {
        super(factoryFacade, new FieldDecryptionFilter());
    }

    @Override
    public Object processType(Object instance) {
        if (null == instance) {
            return null;
        }

        // 处理用户自定义的包装类
        List<Field> allFields = FieldReflectUtils.getAllFields(instance.getClass());

        for (Field field : allFields) {
            field.setAccessible(true);
            TypeProcessFactory processFactory = getFactoryFacade().getProcessFactory(field.getType());
            if (null != processFactory) {
                try {
                    processFactory.processType(field.get(instance));
                } catch (Exception e) {
                    log.error("******************************************");
                    log.error("【获取值，反射异常】field name：{}, 原始对象：{}，具体异常为：", field.getName(), instance, e);
                    log.error("******************************************");
                }
            } else {
                // 基本数据类型 or String.class 类型
                List<FieldFilter> collect = getIncludeTypeFilters().stream().filter(item -> item.isMatch(field)).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(collect) && String.class == field.getType()) {
                    String originalValue = "";
                    try {
                        originalValue = (String) field.get(instance);
                        String processedValue = decryptFieldValue(originalValue);
                        field.set(instance, processedValue);
                    } catch (Exception e) {
                        log.error("******************************************");
                        log.error("【获取值，反射异常】field name：{}, 原始对象：{}，具体异常为：", field.getName(), instance, e);
                        log.error("******************************************");
                    }
                }
            }
        }

        return instance;
    }

    private String decryptFieldValue(String originalValue) {
        if (StringUtils.isNotBlank(originalValue)) {
            SecretContextUtil.SecretContext secretContext = SecretContextUtil.getSecretContext();
            String keyAES128 = secretContext.getKeyAES128();
            String ivAES = secretContext.getIvAES();
            AppConfigProperties configProperties = ApplicationContextUtil.getBean(AppConfigProperties.class);
            if (configProperties.isDevEnv()) {
                return AESUtil.decrypt(keyAES128, originalValue);
            } else {
                return AESUtil.decrypt(keyAES128, originalValue, Base64.getDecoder().decode(ivAES));
            }
        }
        return null;
    }

}
